#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "FileServer.h"
#include <vector>
#include <stdlib.h>
#include <sys/types.h>   
#include <dirent.h>
#include <fstream>

using namespace std ;

FileClientOnServer::FileClientOnServer(int sock , string shareDir)
{
    mSock=sock;
    if( shareDir == "default" ) {
        mShareDir = getenv("HOME") ;
        mShareDir += "/share" ;
    }else {
        mShareDir = shareDir ;
    }
}

void FileClientOnServer::ProcCommand()
{
    mBufBytes = 0 ;
    int nnnn = 0 ;
    while(true){
        mReadBytes= read( mSock , mBuf , 1024 );
        if( mReadBytes == 0)
            break ;
        cout << nnnn++ << ":" << mReadBytes << endl ;
        mBuf[mReadBytes] = 0;
        string str(mBuf) ;
        cout << str << endl ;
        
        string cmdStr = "command:ls" ;
        int pos = str.find(cmdStr) ;
        if( pos != str.npos ) {
            ls() ;            
        }
        cmdStr="command:get" ;
        pos = str.find( cmdStr) ;
        if( pos != str.npos ) {
            int findS = cmdStr.length() + 1 ;//" "
            pos = str.find("\r\n",findS) ;
            if( pos != str.npos ) {
                string fname=str.substr(findS,pos-findS ) ;
                cout <<"get " << fname << endl ;
                sendFile(fname ) ;
            }                    
        }        
    }
}


bool FileClientOnServer::ls()
{
    vector<string> v ;
    DIR * dir;
    struct dirent * ptr;
    int i;
    dir = opendir(mShareDir.c_str());
    if( !dir ) { 
        cout << "open dir " << mShareDir << " fails" << endl ;
        return false ;
    }
    while((ptr = readdir(dir)) != NULL)
    {
        if (ptr->d_type == DT_REG ){
            string fnam = mShareDir+"/"+ptr->d_name ;
            v.push_back( fnam );
        }       
    }
    closedir(dir);
    string str ;
    for( auto it = v.begin(); it!=v.end() ; it ++ ) {
        str += *it ;
        str +="\r\n" ;
    }
    string str1("LEN=") ;
    int len = str1.length() ;
    string str2= to_string( str.length() ) ;
    len += str2.length() ; 
    while( len < 16 ){
        str1+='0';
        len ++ ;
    }
    str1 += str2 ;
    int r = 0 ;
    r = write( mSock , str1.c_str() , len  ) ;
    cout << str1 << " ret:" << r << endl ;
    const char* p = str.c_str() ;
    r = write( mSock , p , str.length() ) ;
    //cout << str << " ret:" << r << endl ;
    bool b = false ;
    if( r ==  str.length() )
        b= true ;
    return b ;    
}


bool FileClientOnServer::sendFile(std::string fname )
{
    ifstream ifs;
    ifs.open( fname,ios::binary ) ;
    ifs.seekg(0,ios::end) ;
    int fsize = ifs.tellg();
    ifs.seekg(0,ios::beg) ;
    string str1("LEN=") ;
    string str2;
    if( fsize < 0 ) {
        str1+="-" ;
        str2= to_string( -fsize ) ; ;
    }else {
        str2= to_string( fsize ) ;
    }
    int len = str1.length() ;
    len += str2.length() ; 
    while( len < 16 ){
        str1+='0';
        len ++ ;
    }
    str1 += str2 ;
    int r = write( mSock , str1.c_str() , len  ) ;
    cout << str1 << " ret:" << r << endl ;
    char aa[101] ;
    int toread = 100 ;
    while ( fsize > 0 ) {
        if ( fsize < toread )
            toread = fsize ;
        ifs.read( aa ,toread ) ;
        int readed = ifs.gcount() ;
         aa[readed]=0 ;
         cout <<aa << endl ;
        fsize -= readed ;
        r = write( mSock , aa  , readed ) ;
    }
        
    return true;    
}


